/**
 * This file is part of Wasagent.
 *
 * Wasagent is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Wasagent is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Wasagent. If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package net.wait4it.wasagent.tests;

import javax.management.ObjectName;

import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.pmi.stat.WSJVMStats;
import com.ibm.websphere.pmi.stat.WSStats;

import net.wait4it.wasagent.jmx.JmxService;
import net.wait4it.wasagent.utils.Result;
import net.wait4it.wasagent.utils.Status;

/**
 * @author Yann Lambret
 *
 */
public class JvmTest extends TestUtils implements Test {

    private static final String message = "jvm test";
    private static final String query = "WebSphere:type=JVM,*";
    


    public Result run(AdminClient client, ObjectName perfMbean, String params) {
        Result result = new Result();
        StringBuilder output = new StringBuilder();
        int code = 0;

        /**
         * Specific test variables
         */
        ObjectName mbean;
        WSStats stats;
        float maxMemory;
        float heapSize;
        float heapUsed;
        float cpu;
        float warning=Float.MAX_VALUE;    
        float critical=Float.MAX_VALUE;

        /**
         * Parse parameters
         */
                // System.out.println("JvmTest.java: Print params:" + params);

        String[] jvmRequestedTests = params.split("\\|"); // splits takes regexp, use \\ to pass a \| to split by |


        try {


            mbean = JmxService.getMbean(client, query);
            //System.out.println(mbean.generateHeapDump());
            // client.invoke(perfMbean, "getStatsObject", params, signature);
            // client.invoke(mbean, "generateHeapDump",null,null);
            /*
             *  String[] signature = new String[] {"javax.management.ObjectName", "java.lang.Boolean"};
             *  Object[] params = new Object[] {mbean, new Boolean(true)};
             *  return (WSStats)client.invoke(perfMbean, "getStatsObject", params, signature);
             *
             *  public java.lang.Object invoke(javax.management.ObjectName name,
             *                                  java.lang.String operationName,
             *                                  java.lang.Object[] params,
             *                                  java.lang.String[] signature)
             *
             *
             * Set<ObjectName> mbeans = client.queryNames(new ObjectName("WebSphere:*,type=Perf"), null);
             * return mbeans.iterator().next(); 
             */

            stats = (WSStats)client.invoke(perfMbean,"getStatsObject",new Object[] {mbean, new Boolean(true)},new String[] {"javax.management.ObjectName", "java.lang.Boolean"});


            maxMemory = format(getBoundedRangeStats(stats, WSJVMStats.HeapSize).getUpperBound());
            heapSize = format(getBoundedRangeStats(stats, WSJVMStats.HeapSize).getCurrent());
            heapUsed = format(getCountStats(stats, WSJVMStats.UsedMemory).getCount());
            cpu = getCountStats(stats, WSJVMStats.cpuUsage).getCount();
            
            for (int i=0; i<jvmRequestedTests.length; i++)
            {
                // System.out.println("JvmTest.java: Parsing:" + jvmRequestedTests[i]);
                String[] paramsArray = jvmRequestedTests[i].split(";");

                if(paramsArray.length>1) {
                        if(paramsArray[1].indexOf("%") != -1) {
                            warning = Long.parseLong(paramsArray[1].replace("%",""));
                            warning = maxMemory * warning * 0.01f;
                        }
                        else 
                            warning = Long.parseLong(paramsArray[1]);
                    

                }
                if(paramsArray.length>2) {
                    if(paramsArray[2].indexOf("%") != -1){
                        critical = Long.parseLong(paramsArray[2].replace("%",""));
                        critical = maxMemory * critical * 0.01f;
                    }
                    else
                        critical = Long.parseLong(paramsArray[2]);
                }

                if(paramsArray[0].toString().equals("heapSize")) {
                        output.append("jvm-heapSize=").append(heapSize).append("MB;"+warning+";"+critical+";0;").append(maxMemory).append(" ");
                        if(code<2 && heapSize>= critical)     code = 2;
                        else if(code<1 && heapSize>=warning)     code = 1;
                }
                 if(paramsArray[0].toString().equals("heapUsed")) {
                        output.append("jvm-heapUsed=").append(heapUsed).append("MB;"+warning+";"+critical+";0;").append(maxMemory).append(" ");
                        if(code<2 && heapUsed>= critical)       code = 2;
                                                else if(code<1 && heapUsed>=warning)    code = 1;
                }
                if(paramsArray[0].toString().equals("cpu")) {
                        output.append("jvm-cpu=").append(cpu).append("%;"+warning+";"+critical+";0;100");
                        if(code<2 && cpu>= critical)       code = 2;
                        else if(code<1 && cpu>=warning)    code = 1;

                }
                
            }

        } catch (Exception e) {
            System.out.println(e.toString());
            result.setStatus(Status.UNKNOWN);
            result.setMessage(Status.UNKNOWN.getMessage(message));
            return result;
        }

        for (Status status : Status.values()) {
            if (code == status.getCode()) {
                result.setStatus(status);
                result.setMessage(status.getMessage(message));
                result.setOutput(output.toString());
                break;
            }
        }

        return result;
    }

}
